package org.bigjava.novelplatform.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import lombok.SneakyThrows;
import org.bigjava.novelplatform.common.exception.UserActionException;
import org.bigjava.novelplatform.entity.Books;
import org.bigjava.novelplatform.entity.Chapter;
import org.bigjava.novelplatform.mapper.BooksMapper;
import org.bigjava.novelplatform.mapper.ChapterMapper;
import org.bigjava.novelplatform.service.AuthorChapterService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.bigjava.novelplatform.common.enums.PublishState.PUBLISHED;
import static org.bigjava.novelplatform.common.enums.PublishState.UNPUBLISHED;
import static org.bigjava.novelplatform.common.enums.VerifyState.PASS_VERIFY;
import static org.bigjava.novelplatform.common.exception.ExceptionCodeMessage.*;
import static org.bigjava.novelplatform.common.exception.ExceptionCodeMessage.NON_COMPLIANT_PARAMETERS;

/**
 * 作者权限管理-文章操作
 */
@Service
public class AuthorChapterServiceImpl implements AuthorChapterService {
    @Resource
    private BooksMapper booksMapper;
    @Resource
    private ChapterMapper chapterMapper;


    /**
     * 添加一篇章节(自动保存为草稿) 参数:章节标题  目标书籍的id 内容
     */
    @Override
    public boolean addChapter(Chapter chapter, String content) {
        //传入的Chapter对象 属性title bookId必须要有值
        String bookUrl = booksMapper.selectBookIDqueryURL(chapter.getBookId());
        if (null == bookUrl) {
            return false;
        }

        chapter.setChapterOrder(-1);//草稿
        chapter.setPublish(UNPUBLISHED);//发布状态 UNPUBLISHED(0,"未发布"),PUBLISHED(1,"已发布");
        chapter.setVerify(PASS_VERIFY);//审核状态 AWAIT(0, "等待"), PASS_VERIFY(1, "通过审核"), SEND_BACK(2, "退回");
        //先将章节信息入库
        if (chapterMapper.insert(chapter) != 1) {
            return false; /*判断章节是否添加成功 insert是线程安全的吗？*/
        }

        //章节文件名示列: 时间戳_章节id_章节标题.txt
        String url =
                bookUrl + "\\" + System.currentTimeMillis() + "_" + chapter.getId() + "_" + chapter.getTitle() + ".txt";
        FileWriter writer = new FileWriter(new File(url));
        writer.write(content);//写入内容

        //正则匹配
        String regex = "</p>";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(content);
        int count = 0;
        while (matcher.find()) {
            count++;
        }
        chapter.setParagraphCount(count + 1);//设置章节段落数量
        chapter.setWordCount(content.length());//该章节的字数

        chapter.setChapterUrl(url);//设置章节完整url
        chapter.setUpdateTime(new Date());
        //更新数据库中章节信息
        return chapterMapper.updateById(chapter) == 1;
    }

    /**
     * 发布章节(将草稿正式发布) 参数:章节id
     */
    @Override
    public boolean releaseChapter(Long chapterid) {
        Chapter chapter = chapterMapper.selectById(chapterid);
        if (null == chapter) {
            return false;
        }
        File file = FileUtil.file(chapter.getChapterUrl());
        FileReader fileReader = new FileReader(file);
        StrBuilder strBuilder = StrUtil.strBuilder(fileReader.readString());

        //正则匹配
        String regex = "</p>";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(strBuilder);
        int count = 0;
        while (matcher.find()) {
            count++;
        }
        chapter.setParagraphCount(count + 1);//设置章节段落数量
        chapter.setWordCount(strBuilder.length());//该章节的字数

        Books books = booksMapper.selectById(chapter.getBookId());
        int Latest = books.getChapter() + 1;//本书最新的章节数量
        books.setLastChapterId(chapter.getId());//设置最新章节id
        books.setLastChapterName(chapter.getTitle());//设置最新章节标题
        books.setUpdateTime(new Date());//设置最新章节更新时间
        books.setChapter(Latest);//设置本书章节数量

        chapter.setChapterOrder(Latest);//设置本章节是本书第几章节(最新章节)
        chapter.setPublish(PUBLISHED);//发布状态 UNPUBLISHED(0,"未发布"),PUBLISHED(1,"已发布");
        books.setWordCount(books.getWordCount() + chapter.getWordCount());//设置本书章节字数

        return chapterMapper.updateById(chapter) == 1 && booksMapper.updateById(books) == 1;
    }

    /**
     * 存贮稿件 参数:章节id 书籍id
     */
    @Override
    public Integer keepChapter(Long chapterId, Integer bookId) {
        Chapter chapter = chapterMapper.selectById(chapterId);
        if (null == chapter) {
            //章节不存在或者该章节已删除
            throw new UserActionException(NONEXISTENT_CHAPTER);
        }
        if (-1 > chapter.getChapterOrder()) {
            //已是处于存贮状态的稿件
            throw new UserActionException(NONEXISTENT_BOOKS);
        }
        //获取这本书中最小的章节数（小于-1）
        Integer MinOrder = chapterMapper.selectAllByChapterOrderMin(bookId);
        if (MinOrder == null) {
            //不存在的书籍
            throw new UserActionException(NONEXISTENT_BOOKS);
        }
        chapter = new Chapter();
        chapter.setChapterOrder(MinOrder - 1);
        chapter.setId(chapterId);
        chapter.setUpdateTime(new Date());
        if (chapterMapper.updateById(chapter) == 1) {
            return chapter.getChapterOrder();
        }
        throw new UserActionException(UNKNOWN_ABNORMAL);
    }

    /**
     * 修改(提交修改) 参数:章节id 章节标题title 提交的内容content state=true/false(覆盖模式/追加模式)
     */
    @SneakyThrows
    @Override
    public boolean modifiedSection(Chapter chapter, String content, Boolean state) {
        //传入的Chapter对象 id title 属性需要有值
        if (chapterMapper.selectChapter(chapter.getId()) == null) {
            return false;
        }
        Chapter chapter1 = chapterMapper.selectById(chapter);

        //从数据库获取该章节的url
        File file = FileUtil.file(chapter1.getChapterUrl());
        //该章节所在的目录
        String fileLs = file.getParent();
        //TODO:没有限制记录文件中的文件个数
        FileUtil.copy(file, new File(fileLs + "\\DeletedChapter\\"), true);
        String[] strlist = FileUtil.getPrefix(file).split("_");//不包含后缀名
        String name = System.currentTimeMillis() + "_" + strlist[1] + "_" + chapter.getTitle() + ".txt";

        //更新数据库中章节的标题和url
        chapter1.setTitle(chapter.getTitle());
        chapter1.setChapterUrl(fileLs + "\\" + name);
        chapter1.setUpdateTime(new Date());
        if (chapterMapper.updateById(chapter1) != 1) {
            return false;
        }

        FileUtil.rename(file, name, true);//更新章节标题
        FileWriter writer = new FileWriter(fileLs + "\\" + name);
        if (state) {//true追加的内容会覆盖原来的内容
            writer.write(content);
            return true;
        }
        writer.append(content);
        return true;
    }

    /**
     * 插入章节
     */
    @Override
    public boolean insertChapter(Chapter chapter) {

        return false;
    }

    /**
     * 删除(逻辑删除)章节 参数: 指定id
     */
    @Override
    public boolean deleteChapter(Long chapterId) {
        Chapter chapter = chapterMapper.selectById(chapterId);

        if (null == chapter) {
            return false;// 表示该章节不存在或者已删除
        }
        if (chapter.getPublish().equals(PUBLISHED)
                && booksMapper.selectAllByIdChapter(chapter.getBookId()).equals(chapter.getId())) {
            return false;//已发布的最新章节不能删
        }

        if(chapter.getChapterOrder() != -1){
            return false;//只能删草稿
        }

        String chapterURL = chapter.getChapterUrl();
        File file = FileUtil.file(chapterURL);//获取目标文件对象
        String chapterNewURL = file.getParent() + "\\DeletedChapter\\";
        File file1 = FileUtil.file(chapterNewURL);//获取目的地文件夹对象

        //1.将文件移动到 删除的文件夹中
        FileUtil.move(file, file1, true);
        File file2 = FileUtil.file(chapterNewURL + FileNameUtil.getName(file));//已移动的文件 对象

        //2.将移动文件重新命名”
        String[] strlist = FileUtil.getPrefix(file).split("_");
        String NewName = System.currentTimeMillis() + "_" + strlist[1] + "_" + strlist[2] + ".txt";
        FileUtil.rename(file2, NewName, false);

        //3.更新数据库中的url字段
        chapter.setChapterUrl(chapterNewURL + NewName);
        chapter.setUpdateTime(new Date());

        return chapterMapper.updateChapterDeleteData(chapter) == 1;
    }

    /**
     * 历史记录恢复 参数:书籍id & 需要恢复的磁盘文件名
     */
    @Override
    public boolean restoreHistory(Integer bookId, String chapterFileName) {
        /*此处传入的是章节文件名 时间戳_章节id_章节标题 */
        String[] list = chapterFileName.split("_");
        String chaOrder = list[1];
        String chaTitle = list[2];

        //此处获取的是未删除的章节文件url
        String url = chapterMapper.selectChapterUrlbyID(Long.valueOf(chaOrder));
        if (!FileUtil.exist(url)) {//如果在未删除的的文件夹中该文件不存在 返回false 继续判断是否在已删除文件夹中

            String bookURL = booksMapper.selectBookIDqueryURL(bookId);//获取书的url
            String chapURL = bookURL + "\\DeletedChapter\\" + chapterFileName + ".txt";

            if (!FileUtil.exist(chapURL)) {
                return false;//如果文件不存在于已删除文件夹中 返回false
            }

            File chaFile1 = FileUtil.file(chapURL);
            FileUtil.move(chaFile1, FileUtil.file(bookURL), true);

            return chapterMapper.updateChapterTitlorStateebyURL(bookId, chapURL, chaTitle,
                    bookURL + "\\" + chapterFileName + ".txt", 0) == 1;
        }

        String url1 = FileUtil.getParent(url, 1);
        File chaFile1 = FileUtil.file(url);
        File chaFile2 = FileUtil.file(url1 + "\\DeletedChapter\\" + chapterFileName + ".txt");

        FileUtil.move(chaFile1, FileUtil.file(url1 + "\\DeletedChapter\\"), true);
        FileUtil.move(chaFile2, FileUtil.file(url1), true);

        //更新数据库数据
        return chapterMapper.updateChapterTitlebyURL(bookId, url, chaTitle, url1 + "\\" + chapterFileName + ".txt") == 1;
    }

    /**
     * 获取指定书籍目录下的DeletedChapter文件夹下的所有文件名集合(不包括后缀名)
     */
    @Override
    public String[] getChangedData(Integer bookid) {
        String bookurl = booksMapper.selectBookIDqueryURL(bookid) + "\\DeletedChapter\\";
        File[] files = FileUtil.ls(bookurl);
        String[] strings = new String[files.length];
        for (int i = 0; i < files.length; i++) {
            strings[i] = FileUtil.getPrefix(files[i]);
        }
        return strings;
    }

    /**
     * 获取指定id章节的历史版本
     */
    @Override
    public List<String> getChapterHistory(Long chapterID) {
        String DeleUrl = FileUtil.getParent(chapterMapper.selectChapterUrlbyID(chapterID), 1) + "\\DeletedChapter\\";
        File[] files = FileUtil.ls(DeleUrl);
        List<String> strings = new ArrayList<String>(5);
        String[] str;
        File file;
        for (int i = 0; i < files.length; i++) {
            file = files[i];
            str = FileUtil.getPrefix(file).split("_");
            if (str[1].equals(String.valueOf(chapterID))) {
                strings.add(FileUtil.getPrefix(file));
            }
        }
        return strings;
    }

    /**
     * 获取指定id章节所在的书籍目录
     */
    public String getChapterUrlById(Long chapterId) {
        return chapterMapper.selectBookUrlByChapterId(chapterId);
    }

    /**
     * 获取已删除的章节 参数:书籍id
     */
    @Override
    public List<String> getChapterDeleted(Integer bookId) {
        if (null == booksMapper.selectById(bookId)) throw new UserActionException(NON_COMPLIANT_PARAMETERS);//书籍不存在
        List<String> list = booksMapper.selectChapterDeletedByBookId(bookId);
        String[] strlist;
        List<String> list1 = new ArrayList<>();
        for (String s : list) {
            strlist = s.split("\\\\");
            String s1 = strlist[strlist.length - 1];
            list1.add(s1);
        }
        return list1;
    }
}
